/*     */ package com.zimbra.cs.dav;
/*     */ 
/*     */ import com.zimbra.common.util.MapUtil;
/*     */ import java.util.ArrayList;
/*     */ import java.util.HashMap;
/*     */ import java.util.List;
/*     */ import java.util.Map;
/*     */ import java.util.UUID;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class LockMgr
/*     */ {
/*     */   private static LockMgr sInstance;
/*     */   private final HashMap<String, List<String>> mLockedResources;
/*     */   private final Map<String, Lock> mLocks;
/*     */   private static final int sDEFAULTTIMEOUT = 600000;
/*     */   private static final String sTIMEOUTINFINITE = "Infinite";
/*     */   private static final String sTIMEOUTSEC = "Second-";
/*     */   private static final String sTOKEN_PREFIX = "urn:uuid:";
/*     */   
/*     */   public static LockMgr getInstance()
/*     */   {
/*  42 */     if (sInstance == null) {
/*  43 */       synchronized (LockMgr.class) {
/*  44 */         if (sInstance == null) {
/*  45 */           sInstance = new LockMgr();
/*     */         }
/*     */       }
/*     */     }
/*  49 */     return sInstance;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private LockMgr()
/*     */   {
/*  59 */     this.mLockedResources = new HashMap();
/*  60 */     this.mLocks = MapUtil.newLruMap(100);
/*     */   }
/*     */   
/*     */   public static enum LockType {
/*  64 */     write;
/*     */     
/*     */     private LockType() {} }
/*  67 */   public static enum LockScope { exclusive,  shared;
/*     */     
/*     */     private LockScope() {}
/*     */   }
/*     */   
/*     */   public static class Lock { public LockMgr.LockType type;
/*     */     public LockMgr.LockScope scope;
/*     */     public String depth;
/*     */     
/*  76 */     public Lock(LockMgr.LockType t, LockMgr.LockScope s, String d, String o) { this.type = t;this.scope = s;this.depth = d;this.owner = o;
/*  77 */       this.expiration = (System.currentTimeMillis() + 600000L);
/*     */     }
/*     */     
/*     */ 
/*     */     public String owner;
/*     */     public long expiration;
/*     */     public String token;
/*     */     public boolean isExpired()
/*     */     {
/*  86 */       return this.expiration < System.currentTimeMillis();
/*     */     }
/*     */     
/*     */ 
/*  90 */     public void extendExpiration() { this.expiration = (System.currentTimeMillis() + 600000L); }
/*     */     
/*     */     public String getTimeoutStr() {
/*  93 */       long timeoutInSec = (this.expiration - System.currentTimeMillis()) / 1000L;
/*  94 */       if (timeoutInSec < 0L)
/*  95 */         return "Infinite";
/*  96 */       return "Second-" + timeoutInSec;
/*     */     }
/*     */     
/*     */ 
/*     */ 
/*     */ 
/* 102 */     public String toLockTokenHeader() { return "<" + this.token + ">"; }
/*     */     
/*     */     public static String parseLockTokenHeader(String token) throws DavException {
/* 105 */       int len = token.length();
/* 106 */       if ((token.charAt(0) == '<') && (token.charAt(len - 1) == '>'))
/* 107 */         return token.substring(1, len - 1);
/* 108 */       throw new DavException("bad Lock-Token", 400);
/*     */     }
/*     */   }
/*     */   
/*     */   public synchronized List<Lock> getLocks(String path) {
/* 113 */     List<Lock> locks = new ArrayList();
/* 114 */     List<String> lockTokens = (List)this.mLockedResources.get(path);
/* 115 */     if (lockTokens != null) {
/* 116 */       for (String token : lockTokens) {
/* 117 */         Lock l = (Lock)this.mLocks.get(token);
/* 118 */         if (l != null)
/*     */         {
/* 120 */           if (l.isExpired()) {
/* 121 */             locks.remove(l);
/*     */           } else
/* 123 */             locks.add(l); }
/*     */       }
/*     */     }
/* 126 */     return locks;
/*     */   }
/*     */   
/*     */   private synchronized Lock hasLock(String owner, String path, LockType type, LockScope scope)
/*     */     throws DavException
/*     */   {
/* 132 */     for (Lock l : getLocks(path))
/* 133 */       if (l != null)
/*     */       {
/* 135 */         if (l.owner.compareTo(owner) == 0)
/* 136 */           return l;
/* 137 */         if (scope == LockScope.exclusive)
/* 138 */           throw new DavException("already locked " + path, 423);
/* 139 */         if ((scope == LockScope.shared) && (l.scope == LockScope.exclusive))
/* 140 */           throw new DavException("shared lock exists " + path, 423);
/*     */       }
/* 142 */     return null;
/*     */   }
/*     */   
/*     */   public synchronized Lock createLock(DavContext ctxt, String owner, String path, LockType type, LockScope scope, String depth) throws DavException {
/* 146 */     Lock l = hasLock(owner, path, type, scope);
/* 147 */     if (l != null)
/* 148 */       return l;
/* 149 */     l = new Lock(type, scope, depth, owner);
/* 150 */     l.token = ("urn:uuid:" + UUID.randomUUID().toString());
/*     */     
/* 152 */     List<String> locks = (List)this.mLockedResources.get(path);
/* 153 */     if (locks == null) {
/* 154 */       locks = new ArrayList();
/* 155 */       this.mLockedResources.put(path, locks);
/*     */     }
/* 157 */     locks.add(l.token);
/* 158 */     this.mLocks.put(l.token, l);
/* 159 */     return l;
/*     */   }
/*     */   
/*     */   public synchronized void deleteLock(DavContext ctxt, String path, String token) {
/* 163 */     List<String> locks = (List)this.mLockedResources.get(path);
/* 164 */     if (locks == null)
/* 165 */       return;
/* 166 */     if (!locks.contains(token))
/* 167 */       return;
/* 168 */     if (this.mLocks.containsKey(token)) {
/* 169 */       this.mLocks.remove(token);
/* 170 */       locks.remove(token);
/*     */     }
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/dav/LockMgr.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */